package com.itfreer.data.general.interceptor.defulat;

import com.itfreer.data.general.IQueryMap;
import com.itfreer.data.general.ITable;
import com.itfreer.data.general.QueryMap;
import com.itfreer.data.general.RelationInfo;
import com.itfreer.data.general.RelationNode;
import com.itfreer.data.general.RowBase;
import com.itfreer.data.general.interceptor.DbEditInterceptorClass;
import com.itfreer.data.general.interceptor.DbEditType;

import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * 定义主子表操作拦截类
 */
public class ChildTableEditInterceptor extends DbEditInterceptorClass {

	public ChildTableEditInterceptor() {
		super.setIndex(-60);
	}
	
	@Override
	public void BeforeDbEditOption(ITable table, Object editEntitys,
			DbEditType editType) {
		if (table == null)
			return;
		RelationNode curNode = table.getRelation();
		if (curNode == null) {
			return;
		}

		if (editType == DbEditType.Delete) {
			if (editEntitys instanceof RowBase) {
				deleteBefore(table, (RowBase) editEntitys);
			} else if (editEntitys instanceof IQueryMap) {
				deleteBefore(table, (IQueryMap) editEntitys);
			}
		}
	}

	@Override
	public void DbEditOptionException(ITable table, Object editEntitys,
			DbEditType editType, Exception ex) {

	}

	@SuppressWarnings("rawtypes")
	@Override
	public void AfterDbEditOption(ITable table, Object editEntitys,
			DbEditType editType) {
		if (table == null)
			return;
		RelationNode curNode = table.getRelation();
		if (curNode == null) {
			return;
		}

		if (editType == DbEditType.Insert) {
			if (editEntitys instanceof RowBase) {
				insertAfter(table, (RowBase) editEntitys);
			} else if (editEntitys instanceof List) {
				insertAfter(table, (List) editEntitys);
			}
		}

		if (editType == DbEditType.Update) {
			if (editEntitys instanceof RowBase) {
				updateAfter(table, (RowBase) editEntitys);
			} else if (editEntitys instanceof List) {
				updateAfter(table, (List) editEntitys);
			}
		}
	}

	@Override
	public String getInterceptorName() {
		return "主子表操作拦截接口";
	}

	/**
	 * 添加新行
	 * 
	 * @param pTable
	 * @param entity
	 */
	protected void insertAfter(ITable pTable, RowBase entity) {
		// 保存子表
		if (entity.getChildValues() == null
				|| entity.getChildValues().size() <= 0) {
			return;
		}

		RelationNode curNode = pTable.getRelation();
		if (curNode == null) {
			return;
		}

		// 添加子表记录
		// 查看每一个子表
		Set<String> keys = entity.getChildValues().keySet();
		for (String key : keys) {
			String tablePK = key.trim().toUpperCase();
			if (!curNode.getChildRelationNode().containsKey(tablePK))
				continue;

			// 与子表的外键
			RelationInfo relationInfo = curNode.getChildRelationNode().get(
					tablePK);

			HashMap<String, String> forKeys = relationInfo.Foreignkey;
			List<RowBase> rows = (List<RowBase>) entity.getChildValues().get(
					key);

			if (forKeys == null || forKeys.size() <= 0 || rows == null
					|| rows.size() <= 0)
				continue;

			// 获取子表
			ITable childTable = pTable.getTableFactory().openTable(tablePK);
			if (childTable == null)
				continue;

			Set<String> forKeySets = forKeys.keySet();
			for (String forKey : forKeySets) {
				Object obj = entity.getValue(forKey);
				for (RowBase row : rows) {
					row.setValue(forKeys.get(forKey), obj);
				}
			}
			childTable.save(rows);
		}
	}

	/**
	 * 批量插入数据
	 * 
	 * @param pTable
	 * @param entitys
	 */
	@SuppressWarnings("rawtypes")
	protected void insertAfter(ITable pTable, List entitys) {
		if (entitys == null || entitys.size() <= 0) {
			return;
		}

		RelationNode curNode = pTable.getRelation();
		if (curNode == null) {
			return;
		}

		HashMap<String, List<RowBase>> rowMap = new HashMap<String, List<RowBase>>();
		for (Object item : entitys) {
			RowBase entity = (RowBase) item;
			if (entity.getChildValues() == null
					|| entity.getChildValues().size() <= 0) {
				continue;
			}

			// 添加子表记录
			// 查看每一个子表
			Set<String> keys = entity.getChildValues().keySet();
			for (String key : keys) {
				String tablePK = key.trim().toUpperCase();
				if (!curNode.getChildRelationNode().containsKey(tablePK))
					continue;

				// 与子表的外键
				RelationInfo relationInfo = curNode.getChildRelationNode().get(
						tablePK);

				HashMap<String, String> forKeys = relationInfo.Foreignkey;
				List<RowBase> rows = (List<RowBase>) entity.getChildValues()
						.get(key);

				if (forKeys == null || forKeys.size() <= 0 || rows == null
						|| rows.size() <= 0)
					continue;

				Set<String> forKeySets = forKeys.keySet();
				for (String forKey : forKeySets) {
					Object obj = entity.getValue(forKey);
					for (RowBase row : rows) {
						row.setValue(forKeys.get(forKey), obj);
					}
				}

				if (rowMap.containsKey(tablePK)) {
					rowMap.get(tablePK).addAll(rows);
				} else {
					rowMap.put(tablePK, rows);
				}
			}
		}
		
		Set<String> tableKeys = rowMap.keySet();
		for (String tableKey : tableKeys) {
			// 获取子表
			ITable childTable = pTable.getTableFactory()
					.openTable(tableKey);
			if (childTable == null)
				continue;
			childTable.save(rowMap.get(tableKey));
		}
	}

	/**
	 * 更新数据行
	 * @param entity
	 */
	protected void updateAfter(ITable pTable, RowBase entity) {
		if (entity == null)
			return;

		// 没有子关系
		RelationNode curNode = pTable.getRelation();
		if (curNode == null) {
			return;
		}

		// 如果有子表信息，处理子表信息
		if (entity.getChildValues() != null
				&& entity.getChildValues().size() > 0) {
			// 查看每一个子表
			HashMap<String, List<RowBase>> childValuesMap = entity
					.getChildValues();
			Set<String> childValuesKeys = entity.getChildValues().keySet();
			for (String childValuesKey : childValuesKeys) {
				String tablePK = childValuesKey.trim().toUpperCase();
				if (!curNode.getChildRelationNode().containsKey(tablePK))
					continue;

				// 与子表的外键
				RelationInfo relationInfo = curNode.getChildRelationNode().get(
						tablePK);

				HashMap<String, String> forKeys = relationInfo.Foreignkey;
				if (forKeys == null || forKeys.size() <= 0)
					continue;

				// 获取子表
				ITable childTable = pTable.getTableFactory().openTable(tablePK);
				if (childTable == null)
					continue;

				// 删除子表相应记录，除当前给定的旧记录外不删除
				List<RowBase> rows = childValuesMap.get(childValuesKey);
				Set<String> forKeysSet = forKeys.keySet();
				
				// 处理旧记录外不删除的操作
				if (rows != null) {
					IQueryMap queryMap = new QueryMap();
					for (String forKey : forKeysSet) {
						queryMap.getWhereMap().put(forKeys.get(forKey),
								entity.getValue(forKey));
					}
					String values = "";
					String key = childTable.getGUIDFieldName();
					for (RowBase row : rows) {
						// 是旧记录
						if (!row.getIsNew()) {
							Object objKey = row.getValue(key);
							values += "'" + objKey.toString() + "',";
						}
					}
					if(values!=""){
						values = values.substring(0, values.length()-1);
						queryMap.getWhereMap().put(key + ":nin", values);
					}
					childTable.delete(queryMap);
				}
				// 将子表信息做为新记录，添加到子表中
				if (rows == null || rows.size() <= 0)
					continue;

				// 对外键赋值
				for (String forKey : forKeysSet) {
					Object obj = entity.getValue(forKey);
					for (RowBase row : rows) {
						row.setValue(forKeys.get(forKey), obj);
					}
				}
				childTable.save(rows);
			}
		}
	}

	/**
	 * 更新数据行
	 */
	@SuppressWarnings("rawtypes")
	protected void updateAfter(ITable pTable, List entitys) {
		if (entitys == null || entitys.size() <= 0)
			return;

		// 没有子关系
		RelationNode curNode = pTable.getRelation();
		if (curNode == null) {
			return;
		}

		HashMap<String, List<RowBase>> rowMap = new HashMap<String, List<RowBase>>();
		for (Object item : entitys) {
			RowBase entity = (RowBase) item;
			if (entity.getChildValues() == null
					|| entity.getChildValues().size() <= 0) {
				continue;
			}

			// 查看每一个子表
			HashMap<String, List<RowBase>> childValuesMap = entity
					.getChildValues();
			Set<String> childValuesKeys = entity.getChildValues().keySet();
			for (String childValuesKey : childValuesKeys) {
				String tablePK = childValuesKey.trim().toUpperCase();
				if (!curNode.getChildRelationNode().containsKey(tablePK))
					continue;

				// 与子表的外键
				RelationInfo relationInfo = curNode.getChildRelationNode().get(
						tablePK);

				HashMap<String, String> forKeys = relationInfo.Foreignkey;
				if (forKeys == null || forKeys.size() <= 0)
					continue;

				// 获取子表
				ITable childTable = pTable.getTableFactory().openTable(tablePK);
				if (childTable == null)
					continue;

				// 删除子表相应记录，除当前给定的旧记录外不删除
				List<RowBase> rows = childValuesMap.get(childValuesKey);
				IQueryMap queryMap = new QueryMap();
				Set<String> forKeysSet = forKeys.keySet();
				for (String forKey : forKeysSet) {
					queryMap.getWhereMap().put(forKeys.get(forKey),
							entity.getValue(forKey));
				}
				
				String values = "";
				String key = childTable.getGUIDFieldName();
				// 处理旧记录外不删除的操作
				if (rows != null && rows.size() > 0) {
					for (RowBase row : rows) {
						// 是旧记录
						if (!row.getIsNew()) {
							Object objKey = row.getValue(key);
							values += "'" + objKey.toString() + "',";
						}
					}
				}
				if(! "".equals(values)){
					values = values.substring(0, values.length()-1);
					queryMap.getWhereMap().put(key + ":nin", values);
				}
				
				childTable.delete(queryMap);

				// 将子表信息做为新记录，添加到子表中
				if (rows == null || rows.size() <= 0)
					continue;

				// 对外键赋值
				for (String forKey : forKeysSet) {
					Object obj = entity.getValue(forKey);
					for (RowBase row : rows) {
						row.setValue(forKeys.get(forKey), obj);
					}
				}

				if (rowMap.containsKey(tablePK)) {
					rowMap.get(tablePK).addAll(rows);
				} else {
					rowMap.put(tablePK, rows);
				}
			}
		}

		Set<String> tableKeys = rowMap.keySet();
		for (String tableKey : tableKeys) {
			// 获取子表
			ITable childTable = pTable.getTableFactory().openTable(tableKey);
			if (childTable == null)
				continue;
			childTable.save(rowMap.get(tableKey));
		}
	}

	/**
	 * 删除表记录
	 * 
	 * @param pTable
	 * @param queryMap
	 */
	protected void deleteBefore(ITable pTable, IQueryMap queryMap) {
		RelationNode curNode = pTable.getRelation();
		if (curNode == null) {
			return;
		}

		Set<String> childKeys = curNode.getChildRelationNode().keySet();
		for (String tablePK : childKeys) {
			// 与子表的外键
			RelationInfo relationInfo = curNode.getChildRelationNode().get(
					tablePK);
			HashMap<String, String> forKeys = relationInfo.Foreignkey;
			// 获取子表
			ITable childTable = pTable.getTableFactory().openTable(tablePK);
			if (childTable == null)
				continue;

			// 删除所有子表
			if (queryMap == null) {
				childTable.delete(queryMap);
			} else {
				// 根据GUID删除相应子表数据和外键
				Set<String> forKeySets = forKeys.keySet();
				String sFields = pTable.getGUIDFieldName() + ",";
				for (String forKey : forKeySets) {
					sFields += forKey + ",";
				}
				sFields = sFields.substring(0, sFields.length()-1);
				queryMap.setSelectFields(sFields);
				List<RowBase> pRows = pTable.getEntityList(RowBase.class, queryMap);
				if (pRows == null || pRows.size() <= 0) {
					return;
				}
				IQueryMap childQueryMap = new QueryMap();
				String fKey = null;
				String fValue = "";
				for (String forKey : forKeySets) {
					for (RowBase row : pRows) {
						Object obj = row.getValue(forKey);
						if (obj == null) {
							continue;
						}
						fValue += "'" + obj.toString() + "',";
					}
					fKey = forKeys.get(forKey);
					break;
				}
				if (fValue != "") {
					fValue = fValue.substring(0, fValue.length() - 1);
				}
				childQueryMap.getWhereMap().put(fKey + ":in", fValue);
				childTable.delete(childQueryMap);
			}
		}
	}

	/**
	 * 删除表记录
	 * 
	 * @param pTable
	 * @param rowBase
	 */
	protected void deleteBefore(ITable pTable, RowBase rowBase) {
		RelationNode curNode = pTable.getRelation();
		if (curNode == null) {
			return;
		}

		Set<String> childKeys = curNode.getChildRelationNode().keySet();
		for (String tablePK : childKeys) {
			// 与子表的外键
			RelationInfo relationInfo = curNode.getChildRelationNode().get(
					tablePK);
			HashMap<String, String> forKeys = relationInfo.Foreignkey;
			// 获取子表
			ITable childTable = pTable.getTableFactory().openTable(tablePK);
			if (childTable == null)
				continue;

			// 删除所有子表
			if (rowBase == null) {
				childTable.delete(new QueryMap());
			} else {
				// 根据GUID删除相应子表数据
				IQueryMap childQueryMap = new QueryMap();
				Set<String> forKeySets = forKeys.keySet();
				String fKey = null;
				String fValue = "";
				for (String forKey : forKeySets) {
					Object obj = rowBase.getValue(forKey);
					if (obj == null) {
						break;
					}
					fValue = "'" + obj.toString() + "'";
					fKey = forKeys.get(forKey);
					break;
				}
				if (fValue != "") {
					childQueryMap.getWhereMap().put(fKey, fValue);
					childTable.delete(childQueryMap);
				}
			}
		}
	}
}